/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#ifndef simodo_sbl_ScriptAnalyzer
#define simodo_sbl_ScriptAnalyzer

/*! \file ScriptAnalyzer.h
    \brief Анализ операторов SBL с использованием внутренней машиной SIMODO
*/

#include "ScriptSemantics_abstract.h"
#include "simodo/interpret/SemanticDataCollector_interface.h"

namespace simodo::interpret
{
    inline constexpr size_t MAX_NUMBER_OF_MISTAKES = 5;

    class ScriptAnalyzer: public ScriptSemantics_abstract
    {
        SemanticDataCollector_interface & _collector;
        size_t                            _number_of_mistakes = 0;

    public:
        ScriptAnalyzer(ModuleManagement_interface & module_management);
        ScriptAnalyzer(ModuleManagement_interface & module_management, SemanticDataCollector_interface & collector);

    // SemanticModule_interface
    public:
        virtual bool             checkInterpretType      (InterpretType interpret_type) const override;
        virtual InterpretState   performOperation        (const ast::Node & op) override;

    // ScriptSemantics_abstract
    public:
        virtual InterpretState   before_start            () override;
        virtual InterpretState   before_finish           (InterpretState state) override;

        // virtual InterpretState   executePushVariable     (const inout::Token & variable_name) override;
        // virtual InterpretState   executeObjectElement    (const ast::Node & op) override;
        // virtual InterpretState   executeFunctionCall     (const ast::Node & op) override;
        virtual InterpretState   executePrint            (bool need_detailed_report) override;
        virtual InterpretState   executeBlock            (bool is_beginning_of_block, const ast::Node & op) override;
        virtual InterpretState   executeImport           (const inout::Token & path, const ast::Node & params) override;
        virtual InterpretState   executeContract         (const ast::Node & op) override;
        virtual InterpretState   executeDeclaration      (const ast::Node & op) override;
        virtual InterpretState   executeDeclarationCompletion() override;
        // virtual InterpretState   executeAssignment       (const ast::Node & op) override;

        virtual InterpretState   executeConditional      (ScriptOperationCode code, const ast::Node & op_true, const ast::Node * op_false) override;

        virtual InterpretState   executeFunctionDefinitionEnd(const ast::Node & op) override;
        // virtual InterpretState   executeReturn           (const ast::Node & op) override;
        virtual InterpretState   executePostAssignment   (const ast::Node & op) override;
        virtual InterpretState   executeCheckState       (const ast::Node & op) override;


        virtual void notifyDeclared(const variable::Variable & variable) override;
        virtual void notifyInitiated(const variable::Variable & ) override;
        virtual void notifyNameUsed(const variable::Variable & variable, const inout::TokenLocation & location) override;
        virtual void notifyRef(const inout::Token & token, const std::u16string & ref) override;  
        virtual void notifyBeforeFunctionCalling(const variable::Variable & function) override;
        virtual void notifyRemoteFunctionLaunch(const inout::TokenLocation & location) override;

    protected:
        void    checkFunctions();  
        void    eraseFunction(const variable::Variable & function);
        variable::Variable makeSelf(const variable::Variable & function_origin, 
                                    const inout::TokenLocation & location);
    };
}

#endif // simodo_sbl_ScriptAnalyzer
